package com.loong.web.gp4j.service.error;

import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.springframework.web.util.HtmlUtils;

import com.loong.tool.lang.Dates;
import com.loong.tool.lang.Requests;
import com.loong.tool.lang.Strings;
import com.loong.web.gp4j.bean.schema.error.ErrorSchema;
import com.loong.web.gp4j.bean.vo.error.ErrorVo;

/**
 * 异常日志封装器
 *
 * @author 张成轩
 */
public class ErrorAdapter {

	/**
	 * @param request
	 * @param type
	 * @param error
	 */
	public static void convert(HttpServletRequest request, String type, ErrorSchema error) {

		String url = (String) request.getAttribute("javax.servlet.error.request_uri");
		if (Strings.isNull(url))
			url = request.getContextPath() + request.getServletPath();
		String param = request.getQueryString();
		error.setUrl(encode(url));
		error.setParam(encode(param));
		error.setIp(Requests.getIp(request));
		error.setTime(Dates.getCurrentTime());
		Exception ex = (Exception) request.getAttribute("javax.servlet.error.exception");
		if (ex != null) {
			error.setType(ex.getClass().getSimpleName());
			error.setMessage(encode(build(ex)));
		} else {
			error.setType(type);
			error.setMessage(request.getHeader("User-Agent"));
		}
	}

	/**
	 * @param ex
	 * @param error
	 */
	public static void convert(Exception ex, ErrorSchema error) {

		error.setType(ex.getClass().getSimpleName());
		error.setTime(Dates.getCurrentTime());
		error.setMessage(encode(build(ex)));
	}

	/**
	 * @param schemas
	 * @param vos
	 */
	public static void convert(List<ErrorSchema> schemas, List<ErrorVo> vos) {

		for (ErrorSchema schema : schemas) {

			ErrorVo vo = new ErrorVo();
			vos.add(vo);
			convert(schema, vo);
		}
	}

	/**
	 * @param schema
	 * @param vo
	 */
	public static void convert(ErrorSchema schema, ErrorVo vo) {

		vo.setIp(schema.getIp());
		vo.setUrl(schema.getUrl());
		vo.setParam(schema.getParam());
		vo.setMessage(schema.getMessage());
		vo.setTime(schema.getTime());
	}

	/**
	 * 获取完整异常信息
	 * 
	 * @param ex 异常对象
	 * @return 异常信息
	 */
	private static String build(Exception ex) {

		StringBuffer error = new StringBuffer();
		error.append(ex.toString());
		int line = 0;
		for (StackTraceElement e : ex.getStackTrace()) {
			if (line++ > 20) {
				error.append("\r\n").append("......");
				break;
			}
			error.append("\r\n").append(e);
		}
		return error.toString();
	}

	/**
	 * 字符串转码
	 * 
	 * @param str 字符串
	 * @return 转码后字符串
	 */
	private static String encode(String str) {

		if (str == null)
			return null;
		return HtmlUtils.htmlEscape(str);
	}
}
